using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using OfficeOpenXml;
using Services.Activity.Domain;
using Services.Activity.Domain.Entities;
using Services.Activity.Infrastructure;
using Services.Activity.WebApi.Request;
using Services.Activity.WebApi.Response;
using Services.Identity.SDK;
using Services.Initial.PublicProject.PublicClass.OutPutModels;
using Services.Initial.PublicProject.PublicMethods;
using SimpleRabbitmq;
using Zack.ASPNETCore;
using Zack.JWT;

namespace Services.Activity.WebApi.Controllers;
[ApiController]
[Route("[controller]/[action]")]
[Authorize]
[UnitOfWork(typeof(ActivityDbContext))]
public class ActivityController(IDomainService domainService, IOptionsSnapshot<JWTOptions> jWTOptions, ITokenService tokenService, IHttpClientFactory httpClientFactory, ActivityDbContext activityDbContext, IEventBus eventBus) : ControllerBase
{
    private readonly IDomainService domainService = domainService;
    private readonly JWTOptions jWTOptions = jWTOptions.Value;
    private readonly ITokenService tokenService = tokenService;
    private readonly IHttpClientFactory httpClientFactory = httpClientFactory;
    private readonly ActivityDbContext activityDbContext = activityDbContext;
    private readonly IEventBus eventBus = eventBus;
    /// <summary>
    /// 创建一个志愿活动
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<OutputModel<CreateActivityResponse>> CreateActivity(CreateActivityRequest request)
    {
        var activityBuilder = new VoluntaryActivity.Builder();
        activityBuilder.SetActivityName(request.ActivityName);
        activityBuilder.SetActivityStartTime(request.ActivityStartTime);
        activityBuilder.SetActivityCompleteTime(request.ActivityCompleteTime);
        activityBuilder.SetActivityDescription(request.ActivityDescription);
        activityBuilder.SetActivityDetailAddress(request.ActivityAddress);
        if (!string.IsNullOrEmpty(request.ActivityAdvertisePhotoBase64))
        {
            string imagePath = await this.domainService.SaveBase64PhotoToImageAsync(request.ActivityAdvertisePhotoBase64, request.ActivityName);
            activityBuilder.SetActivityPhotoPath(imagePath);
        }
        activityBuilder.SetActivityType(request.ActivityType);
        //查询token中的id
        var id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
        activityBuilder.SetOrganizerId(Convert.ToInt64(id));
        var activityId = await this.domainService.ActivityAddAsync(activityBuilder.Build());
        return OutPutMethod<CreateActivityResponse>.Success(new CreateActivityResponse(activityId));
    }
    /// <summary>
    /// 获得多个活动的简要信息
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<OutputModel<List<GetActivitiesDetailResponse>>> GetActivitiesBrief(GetActivitiesDetailRequest req)
    {
        var list = new List<GetActivitiesDetailResponse>();
        var identityClient = new IdentityClient(this.tokenService, this.jWTOptions, this.httpClientFactory);

        var result = await this.domainService.GetActivitiesDetailAsync(req.ActivityIds);
        var query = result.Select(o => o.OrganizerId.ToString()).GroupBy(o => o).Select(o => o.Key).ToList();

        var organizerNames = await identityClient.GetUserInformationByIdsAsync(query);
        // item1 组织者ID item2 组织者名称
        var group = organizerNames.GroupBy(o => o.Item1).ToList();

        foreach (var item in result)
        {
            string organizerName = "";
            foreach (var item2 in group)
            {
                if (long.Parse(item2.Key) == item.OrganizerId)
                {
                    organizerName = item2.First().Item2;
                    break;
                }
            }
            list.Add(new GetActivitiesDetailResponse { ActivityId = item.ActivityId, ActivityName = item.ActivityName, ActivityOrganizerName = organizerName });
        }
        return OutPutMethod<List<GetActivitiesDetailResponse>>.Success(list, 0);
    }
    /// <summary>
    /// 获取一个活动全部详情
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<OutputModel<GetActivityChiefResponse>> GetActivityChief([FromQuery] GetActivityChiefRequest req)
    {
        var result = (await this.domainService.GetActivitiesDetailAsync([req.ActivityId])).First();
        var identityClient = new IdentityClient(this.tokenService, this.jWTOptions, this.httpClientFactory);
        var organizerNames = await identityClient.GetUserInformationByIdsAsync([result.OrganizerId.ToString()]);
        var res = new GetActivityChiefResponse()
        {
            ActivityId = result.ActivityId,
            ActivityName = result.ActivityName,
            ActivityTypes = result.ActivityType.ToString("G"),
            ActivityComplete = result.ActivityComplete,
            ActivityCompleteTime = result.ActivityCompleteTime,
            ActivityDescription = result.ActivityDescription,
            ActivityDetailAddress = result.ActivityDetailAddress,
            ActivityStartTime = result.ActivityStartTime,
            OrganizerName = organizerNames.First().Item2,
            PhotoBase64 = result.PhotoBase64 ?? "",
        };
        return OutPutMethod<GetActivityChiefResponse>.Success(res);
    }
    /// <summary>
    /// 获取活动列表
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<OutputModel<List<long>>> FilterActivity([FromQuery] FilterActivityRequest req)
    {
        var list = await this.domainService.FilterActityIdsByRequestAsync(req.ActivityName, req.OrganizerName, req.ActivityType, req.ActivityStartTime, req.ActivityEndTime, req.ActivityBriefAddress);

        if (list.Count == 0)
        {
            return OutPutMethod<List<long>>.Success(data: list, errType: 1, message: "找不到符合筛选条件的活动");
        }
        else
        {
            return OutPutMethod<List<long>>.Success(list);
        }
    }
    /// <summary>
    /// 参加志愿
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<OutputModel<string>> EnlistVolunteer(EnlistVolunteerRequest request)
    {
        //查询token中的id
        var id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
        var userId = Convert.ToInt64(id);
        await this.domainService.EnlistVolunteerAsync(request.ActivityId, userId);
        await this.eventBus.PublishAsync("VolunteerEnlistActivity", new { UserId = userId, request.ActivityId });
        return OutPutMethod<string>.Success(errType: 1, message: "参加活动成功", data: "");
    }
    /// <summary>
    /// 获得志愿者参加活动列表
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<OutputModel<List<GetVolunteerActivityResponse>>> GetVolunteerActivityList()
    {
        var id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
        var userId = Convert.ToInt64(id);
        var list = await this.domainService.GetVolunteerActivityListAsync(userId);
        var result = list.Select(x => new GetVolunteerActivityResponse { ActivityId = x.ActivityId, ActivityStartTime = x.ActivityStartTime, ActivityEndTime = x.ActivityCompleteTime, ActivityName = x.ActivityName, ActivityType = x.ActivityType.ToString("G"), ActivityEnlistTime = x.Volunteers.First(x => x.VolunteerId == userId).JoinTime, ActivityAddress = x.ActivityDetailAddress, ActivityCompleted = x.ActivityComplete }).ToList();
        return OutPutMethod<List<GetVolunteerActivityResponse>>.Success(result);
    }
    /// <summary>
    /// 获取活动的报名人员列表
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<OutputModel<List<GetActivityVolunteerResponse>>> GetActivityVolunteer([FromQuery] GetActivityVolunteerRequest req)
    {
        var activity = await this.activityDbContext.Activities.Include(x => x.Volunteers).FirstOrDefaultAsync(o => o.ActivityId == req.ActivityId);
        var list = new List<GetActivityVolunteerResponse>();
        list.AddRange(activity!.Volunteers.Select(x => new GetActivityVolunteerResponse { VolunteerId = x.VolunteerId }));
        return OutPutMethod<List<GetActivityVolunteerResponse>>.Success(list);
    }
    /// <summary>
    /// 获取组织者的活动列表
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<OutputModel<List<GetOrganizationActivityListResponse>>> GetOrganizationActivityList()
    {
        var id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
        var userId = Convert.ToInt64(id);
        var activities = await this.domainService.GetOrganizerActivityAsync(userId);
        var result = activities.Select(x => new GetOrganizationActivityListResponse
        {
            ActivityId = x.ActivityId,
            ActivityName = x.ActivityName,
            ActivityCreateTime = x.CreationTime,
            ActivityCompleted = x.ActivityComplete,
            ActivityType = x.ActivityType.ToString("G"),
            ActivityAddress = x.ActivityDetailAddress,
            ActivityStartTime = x.ActivityStartTime,
            ActivityEndTime = x.ActivityCompleteTime
        }).ToList();
        return OutPutMethod<List<GetOrganizationActivityListResponse>>.Success(result);

    }

    /// <summary>
    /// 获取所有准备中的活动
    /// </summary>
    /// <returns>活动excel文件</returns>
    [HttpPost]
    public async Task<IActionResult> GetAllPreparedActivities()
    {
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        // 获取数据
        var activities = await this.activityDbContext.Activities.Select(x => new { x.ActivityId, x.ActivityName, x.ActivityType, x.ActivityStartTime, x.ActivityCompleteTime, x.ActivityDetailAddress, x.ActivityDescription, x.ActivityComplete }).Where(x => !x.ActivityComplete).ToListAsync();

        //创建excel表格
        var excelPackage = new ExcelPackage();
        var worksheet = excelPackage.Workbook.Worksheets.Add("PreparedActivities");

        //设置表头
        worksheet.Cells[1, 1].Value = "活动ID";
        worksheet.Cells[1, 2].Value = "活动名称";
        worksheet.Cells[1, 3].Value = "活动类型";
        worksheet.Cells[1, 4].Value = "活动起始时间";
        worksheet.Cells[1, 5].Value = "活动截止时间";
        worksheet.Cells[1, 6].Value = "活动地点";
        worksheet.Cells[1, 7].Value = "活动描述";
        var row = 2;
        // 写入数据
        foreach (var activity in activities)
        {
            worksheet.Cells[row, 1].Value = activity.ActivityId;
            worksheet.Cells[row, 2].Value = activity.ActivityName;
            worksheet.Cells[row, 3].Value = activity.ActivityType.ToString("G");
            worksheet.Cells[row, 4].Value = activity.ActivityStartTime.ToString("yyyy-MM-dd HH:mm:ss");
            worksheet.Cells[row, 5].Value = activity.ActivityCompleteTime.ToString("yyyy-MM-dd HH:mm:ss");
            worksheet.Cells[row, 6].Value = activity.ActivityDetailAddress;
            worksheet.Cells[row, 7].Value = activity.ActivityDescription;
            row++;
        }
        // 保存文件
        using var memoryStream = new MemoryStream();
        excelPackage.SaveAs(memoryStream);
        return File(memoryStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "PreparedActivities.xlsx");
    }


    /// <summary>
    /// 志愿者签到活动
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    
    [HttpPost]
    public async Task<OutputModel<bool>> VolunteerSignInActivity(VolunteerSignInActivityRequest request)
    {
        var id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
        var userId = Convert.ToInt64(id);
        var result = await this.domainService.VolunteerSignAsync(request.ActivityId, userId);
        return OutPutMethod<bool>.Success(result);
    }
}